/*!
\file Chariot.cpp
\author Po
\brief The chariot object class implementation.
*/
#include "StdAfx.h"
#include "Chariot.h"
#include "Helper.h"
#include "Platform.h"
#include "Time.h"
#include "Input.h"
#include "Enemy.h"
#include <iostream>

using namespace std;

Chariot::Chariot(IDirect3DDevice9 *pd3dDevice)
	: m_pd3dDevice(pd3dDevice),
	m_fSpeed(20.0f),
	m_fMoveX(0.0f),
	m_fMoveZ(0.0f),
	m_fShootDelaySecond(0.25f),
	m_dwLastShootStamp(0),
	m_vecPosition(0.0f, 0.0f, 0.0f),
	m_vecLook(0.0f, 0.0f, 1.0f),
	m_pGun(new Gun(pd3dDevice, 1000.0f))
{
	D3DXCreateCylinder(m_pd3dDevice, 1.0f, 1.0f, 1.5f, 60, 60, &m_pCylinder, 0);
	DrawMeshColor(m_pd3dDevice, &m_pCylinder, 0.0f, 1.0f, 1.0f, 1.0f);
	D3DXMatrixIdentity(&m_matMove);
	D3DXMatrixIdentity(&m_matWorld);
}

Chariot::~Chariot(void)
{
	SAFE_RELEASE(m_pCylinder);
	SAFE_DELETE(m_pGun);
}

void Chariot::SetPlatform(Platform *pPlatform)
{
	m_pPlatform = pPlatform;
	m_vecPosition = m_pPlatform->Position();
	m_matWorld = m_pPlatform->World();
}

void Chariot::SetSpeed(float speed)
{
	m_fSpeed = speed;
}

const D3DXVECTOR3 &Chariot::Position() const
{
	return m_vecPosition;
}

const D3DXVECTOR3 &Chariot::Look() const
{
	return m_vecLook;
}

const D3DXMATRIX &Chariot::World() const
{
	return m_matWorld;
}

void Chariot::UpdateRotationY(float fAngle)
{
	m_fRotationAngleY = fAngle;
}

void Chariot::Update()
{
	if (m_pPlatform == NULL)
	{
		cout << "Chariot::Update() : platform has not been set!" << endl;
		return;
	}

	D3DXMATRIX matSpin;
	D3DXMATRIX matFrameMove;

	D3DXMatrixRotationY(&matSpin, m_fRotationAngleY);
	D3DXMatrixIdentity(&matFrameMove);
	D3DXVec3TransformCoord(&m_vecLook, &D3DXVECTOR3(0.0f, 0.0f, 1.0f), &matSpin);
	D3DXVec3Normalize(&m_vecLook, &m_vecLook);

	D3DXVECTOR3 vecRight;

	D3DXVec3Cross(&vecRight, &D3DXVECTOR3(0.0f, 1.0f, 0.0f), &m_vecLook);

	if (Input::GetKeyDown(DIK_W))
	{
		D3DXVECTOR3 vecForward = m_vecLook * (float)Time::Delta() * m_fSpeed;
		D3DXMatrixTranslation(&matFrameMove, vecForward.x, vecForward.y, vecForward.z);
	}

	if (Input::GetKeyDown(DIK_S))
	{
		D3DXVECTOR3 vecBackward = m_vecLook * -(float)Time::Delta() * m_fSpeed;
		D3DXMatrixTranslation(&matFrameMove, vecBackward.x, vecBackward.y, vecBackward.z);
	}

	if (Input::GetKeyDown(DIK_A))
	{
		D3DXVECTOR3 vecLeftward = vecRight * -(float)Time::Delta() * m_fSpeed;
		D3DXMatrixTranslation(&matFrameMove, vecLeftward.x, vecLeftward.y, vecLeftward.z);
	}

	if (Input::GetKeyDown(DIK_D))
	{
		D3DXVECTOR3 vecRightward = vecRight * (float)Time::Delta() * m_fSpeed;
		D3DXMatrixTranslation(&matFrameMove, vecRightward.x, vecRightward.y, vecRightward.z);
	}

	D3DXMATRIX matVirtualMove = m_matMove * matFrameMove;
	D3DXVECTOR3 vecPlatformCenter(0.0f, 0.0f, 0.0f);

	D3DXVec3TransformCoord(&vecPlatformCenter, &vecPlatformCenter, &matVirtualMove);
	
	if (abs(vecPlatformCenter.x) < m_pPlatform->Width() / 2 && abs(vecPlatformCenter.z) < m_pPlatform->Depth() / 2)
	{
		// Virtual move not exceed platform edge.
		m_matMove = matVirtualMove;
	}

	cout << abs(vecPlatformCenter.x) << " " << m_pPlatform->Width() / 2 << endl;
	cout << abs(vecPlatformCenter.z) << " " << m_pPlatform->Depth() / 2 << endl;

	m_matWorld =  matSpin * m_matMove * m_pPlatform->World();

	D3DXVec3TransformCoord(&m_vecPosition, &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &m_matWorld);

	if (Input::GetButtonDown(0))
	{
		DWORD dwNow = Time::Now();

		if ((dwNow - m_dwLastShootStamp) / 1000.0f > m_fShootDelaySecond)
		{
			m_pGun->Fire(&m_vecPosition, &m_vecLook);
			m_dwLastShootStamp = dwNow;
		}
	}

	m_pGun->Update();

	m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matWorld);
	m_pCylinder->DrawSubset(0);
}


